package com.chuantou.yuba.ui;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.DatePickerDialog;
import android.app.DatePickerDialog.OnDateSetListener;
import android.app.ProgressDialog;
import android.app.TimePickerDialog;
import android.app.TimePickerDialog.OnTimeSetListener;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.TimePicker;
import android.widget.Toast;

import com.android.volley.Request.Method;
import com.android.volley.Response.ErrorListener;
import com.android.volley.Response.Listener;
import com.android.volley.VolleyError;
import com.chuantou.yuba.R;
import com.chuantou.yuba.api.RequestManager;
import com.chuantou.yuba.api.UriHelper;
import com.chuantou.yuba.api.request.GsonRequest;
import com.chuantou.yuba.api.to.BDPoiTO;
import com.chuantou.yuba.api.to.BaseTO;
import com.chuantou.yuba.api.to.CityListTO;
import com.chuantou.yuba.api.to.CityTO;
import com.chuantou.yuba.api.to.UserTO;
import com.chuantou.yuba.util.AccountManager;
import com.chuantou.yuba.util.Constants;
import com.chuantou.yuba.util.DateUtil;
import com.chuantou.yuba.util.UiUtil;
import com.chuantou.yuba.util.ViewHolder;
import com.google.gson.Gson;

/**
 * 发表约钓界面
 * 
 * @author dl1001
 * 
 */
public class PublishFishingActivity extends BaseActionBarActivity implements OnClickListener {
	protected static final int REQUEST_CODE_ADDRESS = 20002;
	private EditText mInputView;
	private TextView mStartTimeView;
	private TextView mEndTimeView;
	private TextView mDistrictView;
	private TextView mAddressView;
	private EditText mFishingPeopleView;
	private EditText mFishingCostView;
	private Date mStartTime;
	private Date mEndTime;
	private CityTO mProvince;
	private CityTO mCity;
	private List<CityTO> mCities;
	private DatePickerDialog mDatePickDialog;
	private ProgressDialog mDialog;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.publish_fishing);
		requestCity();
		setupViews();
		setTitle(R.string.publish_fishing);
	}

	private void setupViews() {
		mInputView = (EditText) findViewById(R.id.content);
		mStartTimeView = (TextView) findViewById(R.id.start_time);
		mEndTimeView = (TextView) findViewById(R.id.end_time);
		mDistrictView = (TextView) findViewById(R.id.district);
		mAddressView = (TextView) findViewById(R.id.address);
		mFishingPeopleView = (EditText) findViewById(R.id.participants);
		mFishingCostView = (EditText) findViewById(R.id.fishing_cost);
		findViewById(R.id.start_time_layout).setOnClickListener(this);
		findViewById(R.id.end_time_layout).setOnClickListener(this);
		findViewById(R.id.district_layout).setOnClickListener(this);
		 findViewById(R.id.address_layout).setOnClickListener(this);
		// findViewById(R.id.participants_layout).setOnClickListener(this);
		// findViewById(R.id.fishing_cost_layout).setOnClickListener(this);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.menu_submit, menu);
		return super.onCreateOptionsMenu(menu);
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case R.id.menu_submit:
			if (UiUtil.isFastDoubleClick()) {
				return true;
			}
			publishFishing();
			return true;
		default:
			break;
		}
		return super.onOptionsItemSelected(item);
	}

	private void publishFishing() {
		String text = mInputView.getText().toString().trim();
		if (TextUtils.isEmpty(text) || text.length() < 5) {
			Toast.makeText(getApplicationContext(), R.string.publish_fishing_hint, Toast.LENGTH_SHORT).show();
			return;
		}

		if (mStartTime == null) {
			Toast.makeText(getApplicationContext(), R.string.input_start_time_error, Toast.LENGTH_SHORT).show();
			return;
		}
		if (mEndTime == null) {
			Toast.makeText(getApplicationContext(), R.string.input_end_time_error, Toast.LENGTH_SHORT).show();
			return;
		}
//		if (mStartTime.getTime() < System.currentTimeMillis()) {
//			Toast.makeText(getApplicationContext(), R.string.input_start_time_earlier_than_now, Toast.LENGTH_SHORT).show();
//			return;
//		}

//		if (mEndTime.getTime() <= mStartTime.getTime()) {
//			Toast.makeText(getApplicationContext(), R.string.input_end_time_earlier_than_start_time, Toast.LENGTH_SHORT).show();
//			return;
//		}
		if (mProvince == null || mCity == null) {
			Toast.makeText(getApplicationContext(), R.string.input_district_error, Toast.LENGTH_SHORT).show();
			return;
		}
		String address = mAddressView.getText().toString().trim();
		if (TextUtils.isEmpty(address)) {
			Toast.makeText(getApplicationContext(), R.string.input_fishing_detail_address_error, Toast.LENGTH_SHORT).show();
			return;
		}
		AccountManager accountManager = AccountManager.getInstance(getApplicationContext());
		if (!accountManager.isLogined()) {
			UiUtil.showNoLoginDialog(this, -1, LoginActivity.ACTION_RETURN);
			return;
		}
		final UserTO user = accountManager.getUserTO();
		if (user.isExpired()) {
			Toast.makeText(this, R.string.message_token_expired, Toast.LENGTH_SHORT).show();
			LoginActivity.start(this, -1, LoginActivity.ACTION_RETURN);
			return;
		}
		int participants = 0;
		try {
			participants = Integer.parseInt(mFishingPeopleView.getText().toString());
		} catch (Exception e) {
			e.printStackTrace();
		}
		int cost = 0;
		try {
			cost = Integer.parseInt(mFishingCostView.getText().toString());
		} catch (Exception e) {
			e.printStackTrace();
		}
		mDialog = new ProgressDialog(PublishFishingActivity.this);
		mDialog.setMessage(getString(R.string.trends_sending));
		mDialog.setCancelable(false);
		mDialog.show();
		String url = UriHelper.getAddFishingUrl();
		HashMap<String, String> params = new HashMap<String, String>();
		params.put(UriHelper.PARAMS_UID, String.valueOf(user.getUid()));
		params.put(UriHelper.PARAMS_TOKEN, user.getToken());
		params.put(UriHelper.PARAMS_CONTENT, text);
		params.put(UriHelper.PARAMS_START, DateUtil.getDateString(mStartTime.getTime(), DateUtil.PATTERN_YYYYMMDDHHMM));
		params.put(UriHelper.PARAMS_END, DateUtil.getDateString(mEndTime.getTime(), DateUtil.PATTERN_YYYYMMDDHHMM));
		params.put(UriHelper.PARAMS_PROVINCE, mProvince.getName());
		params.put(UriHelper.PARAMS_CITY, mCity.getName());
		params.put(UriHelper.PARAMS_ADDRESS, address);
		params.put(UriHelper.PARAMS_PEOPLE, String.valueOf(participants));
		params.put(UriHelper.PARAMS_FEE, String.valueOf(cost));

		GsonRequest<BaseTO> request = new GsonRequest<BaseTO>(Method.POST, url, new Listener<BaseTO>() {

			@Override
			public void onResponse(BaseTO response) {
				if (!hasDestroyed()) {
					if (mDialog != null && mDialog.isShowing()) {
						mDialog.dismiss();
					}
					if (response != null) {
						if (response.isSuccess()) {
							Toast.makeText(getApplicationContext(), R.string.send_success, Toast.LENGTH_SHORT).show();
							sendBroadcast(new Intent(Constants.INTENT_ACTION_SEND_FISHING));
							finish();
						} else {
							if (response.getStatus() == BaseTO.STATUS_TOKEN_ERROR || response.getStatus() == BaseTO.STATUS_TOKEN_EXPIRED) {
								Toast.makeText(getApplicationContext(), R.string.message_token_expired, Toast.LENGTH_SHORT).show();
								LoginActivity.start(PublishFishingActivity.this, -1, LoginActivity.ACTION_RETURN);
							} else {
								String msg = response.getMsg();
								msg = TextUtils.isEmpty(msg) ? getString(R.string.send_failed) : msg;
								Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_SHORT).show();
							}
						}
					} else {
						Toast.makeText(getApplicationContext(), R.string.send_failed, Toast.LENGTH_SHORT).show();
					}
				}
			}
		}, new ErrorListener() {

			@Override
			public void onErrorResponse(VolleyError error) {
				if (!hasDestroyed()) {
					if (mDialog != null && mDialog.isShowing()) {
						mDialog.dismiss();
					}
					Toast.makeText(getApplicationContext(), R.string.request_error, Toast.LENGTH_SHORT).show();
				}
			}
		}, params, BaseTO.class);
		RequestManager.startRequest(getApplicationContext(), request);
	}

	@Override
	public void onClick(View v) {
		if (UiUtil.isFastDoubleClick())
			return;
		switch (v.getId()) {
		case R.id.start_time_layout:
			showDatePickDialog(v, mStartTimeListener);
			break;
		case R.id.end_time_layout:
			showDatePickDialog(v, mEndTimeListener);
			break;
		case R.id.district_layout:
			showProvinceDialog();
			break;
		case R.id.address_layout:
			startActivityForResult(new Intent(this, InputAddressActivity.class), REQUEST_CODE_ADDRESS);
			break;
		default:
			break;
		}
	}

	private void requestCity() {
		String url = UriHelper.getCityUrl();
		GsonRequest<CityListTO> request = new GsonRequest<CityListTO>(Method.POST, url, new Listener<CityListTO>() {

			@Override
			public void onResponse(CityListTO response) {
				if (response == null) {
					response = parseLocalCity();
				}
				if (response != null) {
					mCities = response.getCities();
				}
			}
		}, new ErrorListener() {

			@Override
			public void onErrorResponse(VolleyError error) {
				CityListTO list = parseLocalCity();
				if (list != null) {
					mCities = list.getCities();
				}
			}
		}, null, CityListTO.class);
		RequestManager.startRequest(getApplicationContext(), request);
	}

	private CityListTO parseLocalCity() {
		try {
			InputStream in = getAssets().open("cities");
			BufferedReader reader = new BufferedReader(new InputStreamReader(in));
			String str = reader.readLine();
			Gson gson = new Gson();
			return gson.fromJson(str, CityListTO.class);
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		}
	}

	private void showProvinceDialog() {
		AlertDialog.Builder builder = new AlertDialog.Builder(this);
		builder.setTitle(R.string.choose_district);
		builder.setAdapter(new BaseAdapter() {

			@Override
			public View getView(int position, View convertView, ViewGroup parent) {
				if (convertView == null) {
					convertView = View.inflate(getApplicationContext(), R.layout.city, null);
				}
				CityTO city = mCities.get(position);
				TextView cityView = ViewHolder.get(convertView, R.id.city);
				cityView.setText(city.getName());
				return convertView;
			}

			@Override
			public long getItemId(int position) {
				return position;
			}

			@Override
			public Object getItem(int position) {
				return mCities == null ? null : mCities.get(position);
			}

			@Override
			public int getCount() {
				return mCities == null ? 0 : mCities.size();
			}

		}, new DialogInterface.OnClickListener() {

			@Override
			public void onClick(DialogInterface dialog, int which) {
				CityTO cityTO = mCities.get(which);
				showCityDialog(cityTO);
			}
		});
		builder.create().show();
	}

	private void showCityDialog(final CityTO province) {
		final List<CityTO> cities = province.getCities();
		AlertDialog.Builder builder = new AlertDialog.Builder(this);
		builder.setTitle(province.getName());
		builder.setAdapter(new BaseAdapter() {

			@Override
			public View getView(int position, View convertView, ViewGroup parent) {
				if (convertView == null) {
					convertView = View.inflate(getApplicationContext(), R.layout.city, null);
				}
				CityTO city = cities.get(position);
				TextView cityView = ViewHolder.get(convertView, R.id.city);
				cityView.setText(city.getName());
				return convertView;
			}

			@Override
			public long getItemId(int position) {
				return position;
			}

			@Override
			public Object getItem(int position) {
				return cities == null ? null : cities.get(position);
			}

			@Override
			public int getCount() {
				return cities == null ? 0 : cities.size();
			}

		}, new DialogInterface.OnClickListener() {

			@Override
			public void onClick(DialogInterface dialog, int which) {
				CityTO cityTO = cities.get(which);
				mProvince = province;
				mCity = cityTO;
				String district = String.format("%s %s", mProvince.getName(), mCity.getName());
				mDistrictView.setText(district);
			}
		});
		builder.create().show();
	}

	private void showDatePickDialog(View view, OnDateSetListener listener) {
		view.setClickable(false);
		if (mDatePickDialog != null && mDatePickDialog.isShowing()) {
			return;
		}
		Calendar calendar = Calendar.getInstance();
		int year = calendar.get(Calendar.YEAR);
		int month = calendar.get(Calendar.MONTH);
		int day = calendar.get(Calendar.DAY_OF_MONTH);
		mDatePickDialog = new DatePickerDialog(this, listener, year, month, day);
		mDatePickDialog.show();
		view.setClickable(true);
	}

	private OnDateSetListener mStartTimeListener = new OnDateSetListener() {
		TimePickerDialog mTimePickerDialog;

		@Override
		public void onDateSet(DatePicker view, final int year, final int monthOfYear, final int dayOfMonth) {
			synchronized (this) {
				if (mTimePickerDialog != null && mTimePickerDialog.isShowing())
					return;
				final Calendar calendar = Calendar.getInstance();
				mTimePickerDialog = new TimePickerDialog(PublishFishingActivity.this, new OnTimeSetListener() {

					@Override
					public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
						calendar.set(Calendar.YEAR, year);
						calendar.set(Calendar.MONTH, monthOfYear);
						calendar.set(Calendar.DAY_OF_MONTH, dayOfMonth);
						calendar.set(Calendar.HOUR_OF_DAY, hourOfDay);
						calendar.set(Calendar.MINUTE, minute);
						mStartTime = new Date(calendar.getTimeInMillis());
						String time = DateUtil.getDateString(calendar.getTimeInMillis(), DateUtil.PATTERN_YYYYMMDDHHMM);
						mStartTimeView.setText(time);
					}
				}, calendar.get(Calendar.HOUR_OF_DAY), calendar.get(Calendar.MINUTE), true);
				mTimePickerDialog.show();
			}
		}
	};

	private OnDateSetListener mEndTimeListener = new OnDateSetListener() {
		TimePickerDialog mTimePickerDialog;

		@Override
		public void onDateSet(DatePicker view, final int year, final int monthOfYear, final int dayOfMonth) {
			synchronized (this) {
				if (mTimePickerDialog != null && mTimePickerDialog.isShowing())
					return;
				final Calendar calendar = Calendar.getInstance();
				mTimePickerDialog = new TimePickerDialog(PublishFishingActivity.this, new OnTimeSetListener() {

					@Override
					public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
						calendar.set(Calendar.YEAR, year);
						calendar.set(Calendar.MONTH, monthOfYear);
						calendar.set(Calendar.DAY_OF_MONTH, dayOfMonth);
						calendar.set(Calendar.HOUR_OF_DAY, hourOfDay);
						calendar.set(Calendar.MINUTE, minute);
						mEndTime = new Date(calendar.getTimeInMillis());
						String time = DateUtil.getDateString(calendar.getTimeInMillis(), DateUtil.PATTERN_YYYYMMDDHHMM);
						mEndTimeView.setText(time);
					}
				}, calendar.get(Calendar.HOUR_OF_DAY), calendar.get(Calendar.MINUTE), true);
				mTimePickerDialog.show();
			}
		}
	};
	
	@Override
	public void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		if (resultCode != Activity.RESULT_OK)
			return;
		switch (requestCode) {
		case REQUEST_CODE_ADDRESS:
			BDPoiTO poi = data.getParcelableExtra(Constants.EXTRA_DATA);
			mAddressView.setText(poi.getAddress());
			break;
		default:
			break;
		}
	}

}
